home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / bin / urlgrabber < prev    next >
Encoding:
Text File  |  2010-07-08  |  11.9 KB  |  330 lines

  1. #!/usr/bin/python -t
  2.  
  3. #   This library is free software; you can redistribute it and/or
  4. #   modify it under the terms of the GNU Lesser General Public
  5. #   License as published by the Free Software Foundation; either
  6. #   version 2.1 of the License, or (at your option) any later version.
  7. #
  8. #   This library is distributed in the hope that it will be useful,
  9. #   but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11. #   Lesser General Public License for more details.
  12. #
  13. #   You should have received a copy of the GNU Lesser General Public
  14. #   License along with this library; if not, write to the 
  15. #      Free Software Foundation, Inc., 
  16. #      59 Temple Place, Suite 330, 
  17. #      Boston, MA  02111-1307  USA
  18.  
  19. # This file is part of urlgrabber, a high-level cross-protocol url-grabber
  20. # Copyright 2002-2006 Michael D. Stenner, Ryan Tomayko
  21.  
  22. """NAME
  23.   urlgrabber - a simple client for the urlgrabber python package
  24.  
  25. DESCRIPTION
  26.   This is a thin client for the urlgrabber python package.  It is
  27.   provided mainly for helping debug the python package.  It provides
  28.   low-level access to most urlgrabber features from the shell.
  29.  
  30.   There are two types of options available for this program.  They are
  31.   'client options' and 'module options'.  Client options apply
  32.   specifically to the behavior of this client, whereas module options
  33.   are built-in options to the urlgrabber module.  Both of these are
  34.   avaible from the client command line, but they're documented a
  35.   little differently.  Client options are documented here, and module
  36.   options are documented through the '--help <option>' syntax.
  37.  
  38. CLIENT OPTIONS
  39.   -h, --help
  40.  
  41.      In its short form, (-h) this provides a short usage discription.
  42.      In its long form, it processes the remaining command line as help
  43.      topics.  Legal topics are:
  44.        doc          this info
  45.        options      a list of module options
  46.        <option(s)>  documentation for a given module option
  47.        all          documentation for all module options
  48.  
  49.      Examples:
  50.        urlgrabber --help options
  51.        urlgrabber --help copy_local
  52.  
  53.   -o FILE
  54.  
  55.      By default, downloaded data will be written to a file named using
  56.      the basename of the url.  For example,
  57.      'http://foo.com/index.html' will be written to 'index.html'.  You
  58.      can override this for your convenience or when necessary for urls
  59.      like 'http://foo.com/'
  60.      
  61.   -O
  62.  
  63.      Print the local name of each downloaded file to STDOUT.  This is
  64.      helpful when not using the '-o' option, but is particularly
  65.      useful when using --copy_local=0 (the default) on local files
  66.      because local files will not be copied and the output filename
  67.      will not be the same as that provided with '-o'.
  68.  
  69.   --repeat=N
  70.  
  71.      Grab each url N times.  This is mostly for debugging keepalive.
  72.  
  73.   -p, --progress
  74.  
  75.      Use the default text-based progress meter.
  76.  
  77.   -v, --verbose=N
  78.  
  79.      Increment the verbosity level with each use of '-v' or set it
  80.      directly with --verbose=N.  Currently, distinct levels are 0-2.
  81.      The default is 0.
  82.  
  83.   -d SPEC, --debug=SPEC
  84.  
  85.      Turn on internal urlgrabber debugging.  This is equivalent (but
  86.      overrides) running with the environment variable:
  87.        URLGRABBER_DEBUG=SPEC 
  88.      SPEC can be of the form LEVEL,FILENAME, where
  89.      LEVEL can be string (DEBUG, WARN, etc) or number.
  90.      FILENAME can be the name of a file or "-" for STDOUT.  The
  91.      default is STDERR.  Example: -d1,- logs everything to STDOUT.
  92.      Note: this only works for python > 2.3 because it requires the
  93.      logging package.
  94.  
  95.   -D
  96.  
  97.      A convenience alias for: --verbose=3 --progress --debug=INFO,- 
  98.  
  99.   --profile
  100.  
  101.      Profile the actual fetching and print the results.
  102.  
  103. """
  104.  
  105. MAINHELP = """usage: urlgrabber [options] <url>
  106. urlgrabber - a simple client for the urlgrabber python package
  107.  
  108. options:
  109.   -h, --help        print this message
  110.   --help doc        print basic intro and documentation
  111.   --help options    list available options to the grabber module
  112.   --help <option>   print documentation for a module option
  113.   --help all        print documentation for all module options
  114.   --<option>=VAL    specify a module option. VAL must be a python value,
  115.                     including quotes in the case of strings.
  116.                     e.g.  --user_agent='"foobar/2.0"'
  117.  
  118.   -o FILE           write output to FILE, otherwise the basename of the
  119.                     url will be used
  120.   -O                print the names of saved files to STDOUT
  121.   --repeat=N        grab each URL N times (mostly for debugging keepalive)
  122.   -p, --progress    use the default text progress meter
  123.   -v                increment the verbosity level (defaults to 0)
  124.   --verbose=N       set the verbosity level to N
  125.   -d SPEC, --debug=SPEC
  126.                     turn on urlgrabber module debugging with
  127.                     SPEC=LEVEL,FILENAME.  e.g. -d 1,debug.txt
  128.   -D                a convenience option equivalent to:
  129.                     --verbose=3 --progress --debug=INFO,- 
  130.   --profile         profile the actual fetching and print the results
  131.   """
  132.  
  133. # $Id: urlgrabber,v 1.7 2006/12/08 00:14:16 mstenner Exp $
  134.  
  135. import sys
  136. import getopt
  137. import re
  138.  
  139. import urlgrabber.grabber
  140. from urlgrabber.grabber import URLGrabber, URLGrabberOptions, URLGrabError
  141.  
  142. class client_options:
  143.     def __init__(self):
  144.         self.ug_options, self.ug_defaults = self.get_ug_options()
  145.         self.process_command_line()
  146.     
  147.     def get_ug_options(self):
  148.         ugo = URLGrabberOptions()
  149.         ug_options = ['copy_local', 'keepalive', 'prefix', 'reget',
  150.                       'data', 'quote', 'throttle', 'bandwidth',
  151.                       'proxies', 'retry', 'retrycodes',
  152.                       'range', 'user_agent', 
  153.                       'http_headers', 'ftp_headers', 
  154.                       'ssl_ca_cert', 'ssl_context',
  155.                       'text', 'close_connection',
  156.                       'cache_openers','timeout']
  157.         options_exclude = ['delegate', 'interrupt_callback',
  158.                            'failure_callback', 'urlparser', 'opener',
  159.                            'checkfunc', 'progress_obj']
  160.         for k in ugo.__dict__.keys():
  161.             if (k not in ug_options) and (k not in options_exclude):
  162.                 ug_options.append(k)
  163.                 #print k
  164.         ug_defaults = {}
  165.         for k in list(ug_options):
  166.             try:
  167.                 ug_defaults[k] = repr(getattr(ugo, k))
  168.             except AttributeError:
  169.                 ug_options.remove(k)
  170.         return ug_options, ug_defaults
  171.  
  172.     def process_command_line(self):
  173.         short_options = 'vd:hoOpD'
  174.         long_options = ['profile', 'repeat=', 'verbose=',
  175.                         'debug=', 'help', 'progress']
  176.         ug_long = [ o + '=' for o in self.ug_options ]
  177.         optlist, args = getopt.getopt(sys.argv[1:], short_options,
  178.                                       long_options + ug_long)
  179.         self.verbose = 0
  180.         self.debug = None
  181.         self.outputfile = None
  182.         self.localfile = 0
  183.         self.repeat = 1
  184.         self.progress = 0
  185.         self.profile = 0
  186.         self.ugops = {}
  187.         self.args = args
  188.         
  189.         ug_dash = [ '--' + o for o in self.ug_options ]
  190.         if not args: self.help(args)
  191.         for (o, v) in optlist:
  192.             if o == '--help' or o == '-h': self.help(args)
  193.             if o == '--verbose': self.verbose = v
  194.             if o == '-v':        self.verbose += 1
  195.             if o == '-o':        self.outputfile = v
  196.             if o == '-p' or o == '--progress': self.progress = 1
  197.             if o == '-d' or o == '--debug': self.debug = v
  198.             if o == '--profile': self.profile = 1
  199.             if o == '-O': self.localfile = 1
  200.             if o == '--repeat':
  201.                 try:
  202.                     self.repeat = int(v)
  203.                     if self.repeat < 1: raise ValueError()
  204.                 except ValueError:
  205.                     print 'ERROR: repeat value must be an int >= 1'
  206.                     sys.exit(1)
  207.             if o == '-D':
  208.                 self.verbose = 3
  209.                 self.debug = "INFO,-"
  210.                 self.progress = 1
  211.             if o in ug_dash:
  212.                 try:
  213.                     val = eval(v)
  214.                 except Exception, e:
  215.                     print "error processing option value: %s" % v
  216.                     print e
  217.                     sys.exit(1)
  218.                 else:
  219.                     self.ugops[o[2:]] = val
  220.  
  221.         if len(self.args) > 1 and self.outputfile is not None:
  222.             print "ERROR: cannot use -o when grabbing multiple files"
  223.             sys.exit(1)
  224.  
  225.     def help(self, args):
  226.         if not args:
  227.             print MAINHELP
  228.         else:
  229.             for a in args:
  230.                 m = getattr(self, 'help_'+a, None)
  231.                 if m is not None:
  232.                     m()
  233.                 elif a in self.ug_options:
  234.                     self.help_ug_option(a)
  235.                 else:
  236.                     print 'ERROR: no help on command "%s"' % a
  237.         sys.exit(0)
  238.  
  239.     def help_doc(self):
  240.         print __doc__
  241.  
  242.     def help_options(self):
  243.         width = max(map(len, self.ug_options))
  244.         format  = '  %-' + str(width) + 's = %s'
  245.         hformat = '  %-' + str(width) + 's   %s'
  246.         print hformat % ('OPTION', 'DEFAULT')
  247.         print '-'*(width + 20)
  248.         for k in self.ug_options:
  249.             print format % (k, self.ug_defaults[k])
  250.  
  251.     def help_all(self):
  252.         for k in self.ug_options:
  253.             self.help_ug_option(k)
  254.  
  255.     def help_ug_option(self, option):
  256.         help = ''
  257.         m = re.search(r'^(  '+option+'.*?)\s*^ {,2}\S',
  258.                      urlgrabber.grabber.__doc__, re.M|re.S)
  259.         if m:
  260.             print m.group(1)
  261.         else:
  262.             print '  %s:  no help found for this option' % option
  263.         print ''
  264.             
  265. class ugclient:
  266.     def __init__(self):
  267.         op = client_options()
  268.         self.op = op
  269.         if op.verbose >= 2 and op.ugops:
  270.             print "Module Options:"
  271.             width = max(map(len, op.ugops.keys()))
  272.             format = "  %-" + str(width) + "s = %s"
  273.             for k, v in op.ugops.items():
  274.                 print format % (k, repr(v))
  275.  
  276.         if op.debug:
  277.             self.set_debug_logger(op.debug)
  278.             if hasattr(urlgrabber.grabber, '_log_package_state'):
  279.                 urlgrabber.grabber._log_package_state()
  280.  
  281.         kwargs = dict(op.ugops)
  282.         if op.progress:
  283.             from urlgrabber.progress import text_progress_meter
  284.             kwargs['progress_obj'] = text_progress_meter()
  285.  
  286.         self.g = URLGrabber(**kwargs)
  287.  
  288.     def run(self):
  289.         for url in self.op.args:
  290.             if self.op.verbose: print 'grabbing: %s' % url
  291.             try:
  292.                 for i in range(0, self.op.repeat):
  293.                     f = self.g.urlgrab(url, self.op.outputfile)
  294.                 if self.op.localfile: print f
  295.             except URLGrabError, e:
  296.                 print e
  297.         
  298.     def set_debug_logger(self, dbspec):
  299.         try:
  300.             dbinfo = dbspec.split(',')
  301.             import logging
  302.             level = logging._levelNames.get(dbinfo[0], None)
  303.             if level is None: level = int(dbinfo[0])
  304.             if level < 1: raise ValueError()
  305.             
  306.             formatter = logging.Formatter('%(asctime)s %(message)s')
  307.             if len(dbinfo) > 1: filename = dbinfo[1]
  308.             else: filename = ''
  309.             if filename == '': handler = logging.StreamHandler(sys.stderr)
  310.             elif filename == '-': handler = logging.StreamHandler(sys.stdout)
  311.             else:  handler = logging.FileHandler(filename)
  312.             handler.setFormatter(formatter)
  313.             DBOBJ = logging.getLogger('urlgrabber')
  314.             DBOBJ.addHandler(handler)
  315.             DBOBJ.setLevel(level)
  316.         except (KeyError, ImportError, ValueError):
  317.             DBOBJ = None
  318.         urlgrabber.grabber.set_logger(DBOBJ)
  319.  
  320. if __name__ == '__main__':
  321.     ugc = ugclient()
  322.     if ugc.op.profile:
  323.         import profile
  324.         import pstats
  325.         prof = profile.Profile()
  326.         prof.run('ugc.run()')
  327.         pstats.Stats(prof).strip_dirs().sort_stats('cumulative').print_stats()
  328.     else:
  329.         ugc.run()
  330.